#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

use humansize::{DECIMAL, format_size};
use image::{
    DynamicImage, ExtendedColorType, GenericImageView, ImageReader, Pixel, Rgb, RgbImage,
    imageops::FilterType::Nearest, save_buffer,
};
use slint::{Image, Rgb8Pixel, Rgba8Pixel, SharedPixelBuffer};
use std::borrow::Cow;
use std::fs::metadata;
use std::path::Path;

slint::include_modules!();

pub fn main() -> Result<(), slint::PlatformError> {
    let window = MainWindow::new()?;

    // 打开文件
    window.on_open_file({
        let weak = window.as_weak();
        move || {
            let ui = weak.unwrap();
            let pf = rfd::FileDialog::new()
                .add_filter("图片文件", &["jpg", "jpeg", "png"])
                .pick_file();
            if let Some(path) = pf {
                match open_image(&path) {
                    Ok(img) => {
                        if img.color() == image::ColorType::Rgb8 {
                            ui.set_used_image(Image::from_rgb8(
                                SharedPixelBuffer::<Rgb8Pixel>::clone_from_slice(
                                    img.as_bytes(),
                                    img.width(),
                                    img.height(),
                                ),
                            ));
                            ui.set_color_mode("RGB".into());
                        } else if img.color() == image::ColorType::Rgba8 {
                            ui.set_used_image(Image::from_rgba8(
                                SharedPixelBuffer::<Rgba8Pixel>::clone_from_slice(
                                    img.as_bytes(),
                                    img.width(),
                                    img.height(),
                                ),
                            ));
                            ui.set_color_mode("RGBA".into());
                        } else {
                            ui.invoke_show_popup(false, "不支持的图片类型".into());
                            return;
                        }
                        let size = match metadata(&path) {
                            Ok(metadata) => metadata.len(),
                            Err(_) => 0,
                        };
                        let filename = match Path::new(&path).file_name() {
                            Some(os_str) => os_str.to_string_lossy(),
                            None => Cow::default(),
                        };
                        ui.set_title_text(
                            format!(
                                "{filename}  {}  {}×{} 像素",
                                format_size(size, DECIMAL),
                                img.width(),
                                img.height()
                            )
                            .into(),
                        );
                    }
                    Err(e) => ui.invoke_show_popup(false, e.to_string().into()),
                }
            }
        }
    });

    // 另存为
    window.on_save_as({
        let weak = window.as_weak();
        move || {
            let ui = weak.unwrap();

            let used_image = ui.get_used_image().to_rgb8().unwrap();
            let sf = rfd::FileDialog::new()
                .add_filter("JEPG", &["jpg", "jpeg"])
                .set_file_name(format!(
                    "scissors_{}x{}.jpg",
                    used_image.width(),
                    used_image.height()
                ))
                .save_file();
            if let Some(path) = sf {
                if save_buffer(
                    path,
                    used_image.as_bytes(),
                    used_image.width(),
                    used_image.height(),
                    ExtendedColorType::Rgb8,
                )
                .is_ok()
                {
                    ui.invoke_show_popup(true, "保存成功".into());
                } else {
                    ui.invoke_show_popup(false, "保存失败".into());
                }
            }
        }
    });

    // 关于
    window.on_about(|| {
        AboutBox::new().unwrap().show().unwrap();
    });

    // 蓝底转白底
    window.on_blue_to_white({
        let weak = window.as_weak();
        move || {
            let ui = weak.unwrap();

            let used_image = ui.get_used_image().to_rgb8().unwrap();
            let img = DynamicImage::ImageRgb8(
                RgbImage::from_raw(
                    used_image.width(),
                    used_image.height(),
                    used_image.as_bytes().to_vec(),
                )
                .unwrap(),
            );
            let mut new_img = RgbImage::new(img.width(), img.height());

            let blue_min = Rgb([0, 0, 150]);
            let blue_max = Rgb([152, 216, 255]);

            for (x, y, pixel) in img.pixels() {
                if is_blue_background(pixel.to_rgb(), blue_min, blue_max) {
                    new_img.put_pixel(x, y, Rgb([255, 255, 255]));
                } else {
                    new_img.put_pixel(x, y, pixel.to_rgb());
                }
            }

            ui.set_used_image(Image::from_rgb8(
                SharedPixelBuffer::<Rgb8Pixel>::clone_from_slice(
                    new_img.as_raw(),
                    new_img.width(),
                    new_img.height(),
                ),
            ));
        }
    });

    // 设置为1寸照
    window.on_set_as_one_inch({
        let weak = window.as_weak();
        move || {
            let ui = weak.unwrap();

            let used_image = ui.get_used_image().to_rgb8().unwrap();
            if used_image.width() == 295 && used_image.height() == 413 {
                return;
            }

            let img = DynamicImage::ImageRgb8(
                RgbImage::from_raw(
                    used_image.width(),
                    used_image.height(),
                    used_image.as_bytes().to_vec(),
                )
                .unwrap(),
            )
            .resize_exact(295, 413, Nearest);

            ui.set_used_image(Image::from_rgb8(
                SharedPixelBuffer::<Rgb8Pixel>::clone_from_slice(
                    img.as_bytes(),
                    img.width(),
                    img.height(),
                ),
            ));
        }
    });

    window.run()
}

// 打开图片
fn open_image<P: AsRef<std::path::Path>>(
    path: P,
) -> Result<DynamicImage, image::error::ImageError> {
    let img = ImageReader::open(&path)?.with_guessed_format()?.decode()?;
    Ok(img)
}

// 判断像素是否属于蓝色背景
fn is_blue_background(pixel: Rgb<u8>, min: Rgb<u8>, max: Rgb<u8>) -> bool {
    pixel[0] >= min[0]
        && pixel[0] <= max[0]
        && pixel[1] >= min[1]
        && pixel[1] <= max[1]
        && pixel[2] >= min[2]
        && pixel[2] <= max[2]
}
